#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/11/26 13:40
# @Author  : Niyoufa
from django.http import HttpResponse
from rest_framework.renderers import JSONRenderer
import traceback
import time
from django.conf import settings
from functools import wraps
from django.utils.decorators import available_attrs


class JSONResponse(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """

    def __init__(self, result=None, **kwargs):
        result = result or self.init_response_data()
        content = JSONRenderer().render(result)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

    # 初始化返回参数
    @classmethod
    def init_response_data(cls):
        result = {'code': 200, 'msg': '返回成功','data': {}}
        return result

    # 重置返回参数
    @classmethod
    def reset_response_data(cls, info, code=400):
        result = {'code': code, 'msg': str(info)}
        return result


class CreateException(Exception):
    def __init__(self, error_info):
        self.err = (400, error_info)


class DbException(Exception):
    def __init__(self, error_info):
        self.err = (500, error_info)


class AuthException(Exception):
    def __init__(self, error_info):
        self.err = (401, error_info)


class CustomException(Exception):
    def __init__(self, error_info):
        self.err = (400, error_info)


class TokenException(Exception):
    def __init__(self, error_info):
        self.err = (405, error_info)


class TokenMissException(Exception):
    def __init__(self, error_info):
        self.err = (406, error_info)


class NotFoundException(Exception):
    def __init__(self, error_info):
        self.err = (404, error_info)


class QccInfoNotFoundException(Exception):
    def __init__(self, error_info):
        self.err = (407, error_info)

# 接口视图异常处理装饰器
def exception_handler(func):
    def handler(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except (CreateException,
                DbException,
                CustomException,
                TokenException,
                TokenMissException,
                AuthException,
                NotFoundException) as msg:
            code = msg.err[0]
            info = msg.err[1]
            result = JSONResponse.reset_response_data(
                str(info), code=int(code))
            response = JSONResponse(result)
            response.status_code = 200
            return response
        except BaseException:
            if settings.DEBUG == True:
                info = traceback.format_exc()
                result = JSONResponse.reset_response_data(str(info), code=500)
            else:
                info = "服务器开小差啦"
                result = JSONResponse.reset_response_data(info, code=500)
            response = JSONResponse(result)
            response.status_code = 200
            return response
    return handler


def time_consume(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        time_useage = time.time() - start_time
        settings.APILOG.info("{func_name}:{time_useage}ms".format(
            func_name=func.__name__,
            time_useage=int(time_useage * 1000)
        ))
        return result
    return wrapper


def params(args):  # 接收传入的字段
    """
    参数检查
    """
    def check_params(func):
        @wraps(func, assigned=available_attrs(func))
        def in_fun(request,*para,**kw):
            for val in args:  # 遍历客户端请求是否包含字段
                if val not in request.data and val not in  request.query_params:  # 若不包含则返回错误
                    return response_failure('缺少参数必要参数')
            return func(request,*para,**kw)
        return in_fun
    return check_params


def response_failure(info):
    """
    失败返回
    """
    result = JSONResponse.reset_response_data(
        str(info), code=400)
    response = JSONResponse(result)
    response.status_code = 200
    return response


def verify_permission(need_permission):
    def deco(func):
        def wrapper(request,*args, **kwargs):
            if not request.session.get("permissions") or need_permission not in request.session.get("permissions"):
                code = 400
                info = "当前用户不具有{}权限".format(need_permission)
                result = JSONResponse.reset_response_data(
                    str(info), code=int(code))
                response = JSONResponse(result)
                response.status_code = 200
                return response
            return func(request,*args, **kwargs)
        return wrapper
    return deco